//this file is part of eMule
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


// SearchDlg.cpp : implementation file
//

//#include "stdafx.h"
#include "emule.h"
#include "SearchDlg.h"
#include "packets.h"
#include "server.h"
#include "opcodes.h"
#include "otherfunctions.h"
#include "ED2KLink.h"

// CSearchDlg dialog
#include "muuli_wdr.h"

#include "pixmaps/close.xpm"
#include "pixmaps/close_hi.xpm"
#include "pixmaps/SearchResults.ico.xpm"

#include "wx/xrc/xmlres.h"
#include "wx/xrc/xh_all.h"

#define ID_SEARCHTIMER 55219

#define GetDlgItem(x,clas) XRCCTRL(*this,#x,clas)
#define IsDlgButtonChecked(x) XRCCTRL(*this,#x,wxCheckBox)->GetValue()
#define CheckDlgButton(x,y) XRCCTRL(*this,#x,wxCheckBox)->SetValue(y)

// just to keep compiler happy
static wxCommandEvent nullEvent;

IMPLEMENT_DYNAMIC_CLASS(CSearchDlg,wxPanel)

BEGIN_EVENT_TABLE(CSearchDlg, wxPanel)
  EVT_BUTTON(XRCID("IDC_STARTS"), CSearchDlg::OnBnClickedStarts)
  EVT_BUTTON(XRCID("IDC_CANCELS"),CSearchDlg::OnBnClickedCancels)
  EVT_TIMER(ID_SEARCHTIMER, CSearchDlg::OnTimer)
  EVT_LIST_ITEM_RIGHT_CLICK(ID_SEARCHLISTCTRL,CSearchDlg::OnRclick)
  EVT_BUTTON(XRCID("IDC_SDOWNLOAD"),CSearchDlg::OnBnClickedSdownload)
  EVT_MULENOTEBOOK_PAGE_CLOSED(XRCID("ID_NOTEBOOK"),CSearchDlg::OnSearchClosed)
  EVT_TEXT_ENTER(XRCID("IDC_SEARCHNAME"),CSearchDlg::OnBnClickedStarts)
  EVT_TEXT_ENTER(XRCID("IDC_SEARCHAVAIL"),CSearchDlg::OnBnClickedStarts)
  EVT_TEXT_ENTER(XRCID("IDC_SEARCHEXTENTION"),CSearchDlg::OnBnClickedStarts)
  EVT_TEXT_ENTER(XRCID("IDC_SEARCHMINSIZE"),CSearchDlg::OnBnClickedStarts)
  EVT_TEXT_ENTER(XRCID("IDC_SEARCHMAXSIZE"),CSearchDlg::OnBnClickedStarts)
  EVT_BUTTON(XRCID("IDC_SEARCH_RESET"),CSearchDlg::OnBnClickedSearchReset)
  EVT_BUTTON(XRCID("IDC_CLEARALL"),CSearchDlg::OnBnClickedClearall)
  EVT_LIST_COL_CLICK(ID_SERVERLIST,CSearchDlg::OnColumnClick)
END_EVENT_TABLE()

  //  EVT_MENU(MP_RESUME,CSearchDlg::OnBnClickedSdownload)

void CSearchDlg::OnColumnClick(wxListEvent& evt)
{
  printf("COLCLICK\n");
}

  // we must implement Rclick here as wxWindows does not redirect events correctly :(
void CSearchDlg::OnRclick(wxListEvent& event)
{
 // change selection
  CSearchListCtrl* src=(CSearchListCtrl*)event.GetEventObject();
  
  //if(src) 
    //src->OnRclick(event);    
}

void CSearchDlg::OnSearchClosed(CMuleNotebookEvent& evt)
{
      // yes it is more than confusing.. to make things even a bit easier
      // we'll prevent closing if search is active.

 // Madcat: Removing this check for now, seems to work fine w/o it.
 //  if(XRCCTRL(*this,"IDC_STARTS",wxButton)->IsEnabled()) {

    // then query the search id
    CMuleNotebook* nb=XRCCTRL(*this,"ID_NOTEBOOK",CMuleNotebook);
    wxWindow* page=(wxWindow*)nb->GetPage(evt.GetSelection());
    CSearchListCtrl* sl=(CSearchListCtrl*)page->FindWindowById(ID_SEARCHLISTCTRL,page);
    if(!sl) {
      // hmm? can this happen?
      return; // do not close anything then
    }
    uint16 sID=sl->GetSearchId();
    // and then finally. close the tab
    DeleteSearch(sID);
 //  }
}

wxSizer* buildGUI(CSearchDlg* parent)
{
  // this is a hand-made reconstruction from emule.rc
  // don't bother to stuff any strings here inside _("") or wxT("")
  // everything is set anyway in Localize()

  // base sizer
  wxBoxSizer* root=new wxBoxSizer(wxVERTICAL);

  // first row: different search boxes
  wxBoxSizer* row1=new wxBoxSizer(wxHORIZONTAL);

  // then first row columns
  // first: Search
  wxStaticBox* sbox=new wxStaticBox(parent,XRCID("IDC_SEARCH_FRM"),"Search");
  wxStaticBoxSizer* sbi1=new wxStaticBoxSizer(sbox,wxHORIZONTAL);
  // add search box to the 1st row
  row1->Add(sbi1,3,wxGROW|wxRIGHT,4);
  
  // search box: two columns
  wxBoxSizer* scol1=new wxBoxSizer(wxVERTICAL);
  wxBoxSizer* scol2=new wxBoxSizer(wxVERTICAL);

  // left column
  wxStaticText* txt=new wxStaticText(parent,XRCID("IDC_MSTATIC3"),"Name");
  scol1->Add(txt,0,wxALIGN_LEFT,0);
  wxTextCtrl* edt=new wxTextCtrl(parent,XRCID("IDC_SEARCHNAME"),wxT(""),wxDefaultPosition,
				 wxSize(128,-1),wxTE_PROCESS_ENTER);
  scol1->Add(edt,0,wxALIGN_LEFT|wxGROW|wxALL,0);
  txt=new wxStaticText(parent,XRCID("IDC_MSTATIC4"),"Type");
  scol1->Add(txt,0,wxALIGN_LEFT,0);
  wxChoice* choi=new wxChoice(parent,XRCID("IDC_TypeSearch"),wxDefaultPosition,wxSize(129,-1));
  scol1->Add(choi,0,wxALIGN_LEFT|wxGROW|wxALL,0);
  
  txt=new wxStaticText(parent,-1,wxT("")); // this will act as empty space
  wxCheckBox *check=new wxCheckBox(parent,XRCID("IDC_SGLOBAL"),"Search global",wxDefaultPosition,
				   wxSize(100,-1));
  scol1->Add(txt,1,wxALIGN_LEFT|wxGROW|wxALL,0);
  scol1->Add(check,0,wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL,0);

  // right column
  wxBoxSizer* hbox=new wxBoxSizer(wxHORIZONTAL);
  txt=new wxStaticText(parent,XRCID("IDC_SEARCHMINSIZE"),"min Size:",wxDefaultPosition,
		       wxSize(120,-1));
  edt=new wxTextCtrl(parent,XRCID("IDC_EDITSEARCHMIN"),wxT(""),wxDefaultPosition,wxSize(48,-1),wxTE_PROCESS_ENTER);
  hbox->Add(txt,0,wxALIGN_CENTER_VERTICAL|wxALL,0);
  hbox->Add(edt,1,wxGROW|wxALIGN_LEFT|wxALL,0);
  scol2->Add(hbox,0,wxALIGN_LEFT|wxALIGN_TOP|wxBOTTOM,2);

  hbox=new wxBoxSizer(wxHORIZONTAL);
  txt=new wxStaticText(parent,XRCID("IDC_SEARCHMAXSIZE"),"max Size:",wxDefaultPosition,
		       wxSize(120,-1));
  edt=new wxTextCtrl(parent,XRCID("IDC_EDITSEARCHMAX"),wxT(""),wxDefaultPosition,
		     wxSize(48,-1),wxTE_PROCESS_ENTER);
  hbox->Add(txt,0,wxALIGN_CENTER_VERTICAL|wxALL,0);
  hbox->Add(edt,1,wxGROW|wxALIGN_LEFT|wxALL,0);
  scol2->Add(hbox,0,wxALIGN_LEFT|wxALIGN_TOP|wxTOP|wxBOTTOM,2);

  hbox=new wxBoxSizer(wxHORIZONTAL);
  txt=new wxStaticText(parent,XRCID("IDC_SEARCHEXTENTION"),"Extension",wxDefaultPosition,
		       wxSize(120,-1));
  edt=new wxTextCtrl(parent,XRCID("IDC_EDITSEARCHEXTENSION"),wxT(""),wxDefaultPosition,
		     wxSize(48,-1),wxTE_PROCESS_ENTER);
  hbox->Add(txt,0,wxALIGN_CENTER_VERTICAL|wxALL,0);
  hbox->Add(edt,1,wxGROW|wxALIGN_LEFT|wxALL,0);
  scol2->Add(hbox,0,wxALIGN_LEFT|wxALIGN_TOP|wxTOP|wxBOTTOM,2);

  hbox=new wxBoxSizer(wxHORIZONTAL);
  txt=new wxStaticText(parent,XRCID("IDC_SEARCHAVAIL"),"Availablility",wxDefaultPosition,
		       wxSize(120,-1));
  edt=new wxTextCtrl(parent,XRCID("IDC_EDITSEARCHAVAIBILITY"),wxT(""),wxDefaultPosition,
		     wxSize(48,-1),wxTE_PROCESS_ENTER);
  hbox->Add(txt,0,wxALIGN_CENTER_VERTICAL|wxALL,0);
  hbox->Add(edt,1,wxGROW|wxALIGN_LEFT|wxALL,0);
  scol2->Add(hbox,0,wxALIGN_LEFT|wxALIGN_TOP|wxTOP|wxBOTTOM,2);

  wxButton* reset=new wxButton(parent,XRCID("IDC_SEARCH_RESET"),"Reset",wxDefaultPosition,wxDefaultSize,0);
  scol2->Add(reset,0,wxALIGN_RIGHT|wxALIGN_BOTTOM|wxTOP,2);

  // add columns to search box
  sbi1->Add(scol1,1,wxALIGN_TOP|wxRIGHT|wxGROW,4);
  sbi1->Add(scol2,0,wxALIGN_TOP|wxGROW|wxLEFT,4);

  // web based search-box
  sbox=new wxStaticBox(parent,XRCID("IDC_WEBSEARCH_FRM"),"Web-based Search");
  sbi1=new wxStaticBoxSizer(sbox,wxVERTICAL);

  txt=new wxStaticText(parent,XRCID("IDC_NAME21"),"Name");
  edt=new wxTextCtrl(parent,XRCID("IDC_SWEB"),wxT(""),wxDefaultPosition,
		     wxSize(224,-1),wxTE_PROCESS_ENTER);
  sbi1->Add(txt,0,wxALIGN_TOP|wxALL,0);
  sbi1->Add(edt,0,wxALIGN_TOP|wxGROW|wxALIGN_LEFT|wxALL,0);

  txt=new wxStaticText(parent,XRCID("IDC_MSTATIC7"),"Type");
  choi=new wxChoice(parent,XRCID("IDC_COMBO1"),wxDefaultPosition,wxSize(115,-1));
  sbi1->Add(txt,0,wxALIGN_TOP|wxALL,0);
  sbi1->Add(choi,0,wxALIGN_TOP|wxGROW|wxALIGN_LEFT|wxALL,0);

  // add web-based box to 1st row
  row1->Add(sbi1,0,wxGROW|wxALIGN_LEFT|wxALL,0);

  // and the last box. the direct download
  sbox=new wxStaticBox(parent,XRCID("IDC_DDOWN_FRM"),"Direct download");
  sbi1=new wxStaticBoxSizer(sbox,wxVERTICAL);

  txt=new wxStaticText(parent,XRCID("IIDC_FSTATIC2"),"ED2K Link");
  edt=new wxTextCtrl(parent,XRCID("IDC_ELINK"),wxT(""),wxDefaultPosition,
		     wxSize(74,-1),wxTE_PROCESS_ENTER|wxTE_MULTILINE);
  sbi1->Add(txt,0,wxALIGN_TOP|wxALIGN_LEFT|wxALL,0);
  sbi1->Add(edt,1,wxALIGN_TOP|wxALIGN_LEFT|wxGROW|wxALL,0);

  // add dow to the page
  row1->Add(sbi1,1,wxGROW|wxALIGN_LEFT|wxLEFT|wxRIGHT,4);

  // 2nd row: start / cancel / remove all
  wxBoxSizer* row2=new wxBoxSizer(wxHORIZONTAL);
  wxStaticBitmap* bmp=new wxStaticBitmap(parent,-1,wxBitmap(SearchResults_ico));
  row2->Add(bmp,0,wxALIGN_LEFT|wxALIGN_BOTTOM|wxRIGHT,8);
  txt=new wxStaticText(parent,XRCID("IDC_RESULTS_LBL"),"Search results");
  row2->Add(txt,1,wxALIGN_LEFT|wxGROW|wxALIGN_BOTTOM|wxTOP,8);

  wxButton* but=new wxButton(parent,XRCID("IDC_STARTS"),"Start",wxDefaultPosition,
			     wxSize(74,22));
  row2->Add(but,0,wxALIGN_LEFT|wxRIGHT,4);
  but=new wxButton(parent,XRCID("IDC_CANCELS"),"Cancel",wxDefaultPosition,
		   wxSize(74,22));
  row2->Add(but,0,wxALIGN_LEFT|wxRIGHT,4);
  but=new wxButton(parent,XRCID("IDC_CLEARALL"),"Clear all",wxDefaultPosition,
		   wxSize(74,22));
  row2->Add(but,0,wxALIGN_LEFT|wxALL,0);

  // add rows
  root->Add(row1,0,wxGROW|wxALIGN_LEFT|wxALL,0);
  root->Add(row2,0,wxALIGN_LEFT|wxTOP|wxGROW,4);

  // notebook
  CMuleNotebook* book=new CMuleNotebook(parent,XRCID("ID_NOTEBOOK"),wxDefaultPosition,
					wxSize(200,190),0);
  root->Add(book,1,wxGROW|wxALIGN_LEFT|wxALIGN_TOP|wxTOP,4);

  // and download selected
  but=new wxButton(parent,XRCID("IDC_SDOWNLOAD"),"Download selected",wxDefaultPosition,
		   wxSize(120,22));
  root->Add(but,0,wxALIGN_LEFT|wxTOP,4);

  parent->SetAutoLayout(TRUE);
  parent->SetSizer(root);
  root->Fit(parent);
  root->SetSizeHints(parent);
  return root;
}

//IMPLEMENT_DYNAMIC(CSearchDlg, CDialog)
CSearchDlg::CSearchDlg(wxWindow* pParent /*=NULL*/)
  : wxPanel(pParent,CSearchDlg::IDD),
    m_timer(this,ID_SEARCHTIMER)
{
  m_nSearchID = 0;
  
  searchpacket=NULL;
  searchprogress=NULL; // will be set later...

  SetBackgroundColour(GetColour(wxSYS_COLOUR_WINDOW));
  //wxSizer* content=searchDlg(this,TRUE);
  //content->Show(this,TRUE);
  
  wxSizer* content=buildGUI(this);
  content->Show(this,TRUE);
  //SetAutoLayout(TRUE);

  // not anymore:
  //content=searchDlg(this,FALSE);
  //content->Show(this,TRUE);

  // initialise the image list
  m_ImageList.Add(wxBitmap(close_xpm));
  m_StateImageList.Add(wxBitmap(close_hi_xpm));
  // and set it to the notebook too...
  XRCCTRL(*this,"ID_NOTEBOOK",CMuleNotebook)->SetImageList(&m_ImageList);
  XRCCTRL(*this,"ID_NOTEBOOK",CMuleNotebook)->SetStateImageList(&m_StateImageList);
  //wxStaticCast(FindWindowById(ID_NOTEBOOK),CMuleNotebook)->SetImageList(&m_ImageList);
  //wxStaticCast(FindWindowById(ID_NOTEBOOK),CMuleNotebook)->SetStateImageList(&m_StateImageList);

  Localize();

  searchlistctrl=NULL;
}

CSearchDlg::~CSearchDlg(){
}

#if 0
BOOL CSearchDlg::OnInitDialog(){
	CResizableDialog::OnInitDialog();
	Localize();
	searchlistctrl.Init(theApp.searchlist);
	searchprogress.SetStep(1);
	global_search_timer = 0;
	globsearch = false;

	m_ctrlSearchFrm.Init(IDI_NORMALSEARCH);
	m_ctrlWebSearchFrm.Init(IDI_WEBBASED);
	m_ctrlDirectDlFrm.Init(IDI_DIRECTDOWNLOAD);
	((CStatic*)GetDlgItem(IDC_SEARCHLST_ICO))->SetIcon((HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_SEARCHRESULTS), IMAGE_ICON, 16, 16, 0));

	searchselect.ShowWindow(SW_HIDE);
	m_ImageList.Create(16,16,ILC_COLOR32|ILC_MASK,0,10);
	m_ImageList.SetBkColor(CLR_NONE);
	m_ImageList.Add(theApp.LoadIcon(IDI_BN_SEARCH));
	searchselect.SetImageList(&m_ImageList);

	AddAnchor(IDC_SDOWNLOAD,BOTTOM_RIGHT);
	AddAnchor(IDC_SEARCHLIST,TOP_LEFT,BOTTOM_RIGHT);
	AddAnchor(IDC_PROGRESS1,BOTTOM_LEFT,BOTTOM_RIGHT);

	AddAnchor(IDC_MSTATIC6, TOP_LEFT, TOP_RIGHT);
	//AddAnchor(IDC_FSTATIC2, TOP_LEFT);
	AddAnchor(IDC_ELINK, TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_STARTS, TOP_RIGHT);
	AddAnchor(IDC_CANCELS, TOP_RIGHT);
	AddAnchor(IDC_CLEARALL, TOP_RIGHT);
	AddAnchor(searchselect.m_hWnd,TOP_LEFT,TOP_RIGHT);
	return true;
}
#endif

#if 0
void CSearchDlg::DoDataExchange(CDataExchange* pDX){
	CResizableDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_SEARCHLIST, searchlistctrl);
	DDX_Control(pDX, IDC_PROGRESS1, searchprogress);
	DDX_Control(pDX, IDC_Type, typebox);
	DDX_Control(pDX, IDC_TypeSearch, Stypebox);
	DDX_Control(pDX, IDC_TAB1, searchselect);
	DDX_Control(pDX, IDC_SEARCH_FRM, m_ctrlSearchFrm);
	DDX_Control(pDX, IDC_WEBSEARCH_FRM, m_ctrlWebSearchFrm);
	DDX_Control(pDX, IDC_DDOWN_FRM, m_ctrlDirectDlFrm);
}
#endif


#if 0
BEGIN_MESSAGE_MAP(CSearchDlg, CResizableDialog)
	ON_BN_CLICKED(IDC_STARTS, OnBnClickedStarts)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_CANCELS, OnBnClickedCancels)
	ON_BN_CLICKED(IDC_SDOWNLOAD, OnBnClickedSdownload)
	ON_NOTIFY(NM_DBLCLK, IDC_SEARCHLIST, OnNMDblclkSearchlist)
	ON_BN_CLICKED(IDC_CLEARALL, OnBnClickedClearall)
	ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnTcnSelchangeTab1)
END_MESSAGE_MAP()
#endif


// CSearchDlg message handlers

typedef void (CSearchListCtrl::*slistFunc)(wxListEvent&);

void CSearchDlg::OnBnClickedStarts(wxEvent& ev){
// Just in case, abort previous global search.
  OnBnClickedCancels(nullEvent);
  wxTextCtrl* ctl=XRCCTRL(*this,"IDC_ELINK",wxTextCtrl);
  if(ctl->GetLineText(0).Length()) {
    wxString strlink=ctl->GetLineText(0);
    if(strlink.Right(1)!="/") strlink+="/";
    ctl->SetValue("");
    try {
      CED2KLink* pLink=CED2KLink::CreateLinkFromUrl(strlink);
      assert(pLink!=0);
      if(pLink->GetKind()==CED2KLink::kFile) {
	theApp.downloadqueue->AddFileLinkToDownload(pLink->GetFileLink());
      } else {
	throw wxString(_("bad link"));
      }
      delete pLink;
    } catch(wxString error) {
      char buffer[200];
      sprintf(buffer,GetResString(IDS_ERR_INVALIDLINK),error.GetData());
      theApp.emuledlg->AddLogLine(true,GetResString(IDS_ERR_LINKERROR),buffer);
    }
    return;
  }

#if 0
  if (GetDlgItem(IDC_SWEB)->GetWindowTextLength()){
    ShellOpenFile(CreateWebQuery());
    return;
  }
#endif

  // start search
  StartNewSearch();

}

void CSearchDlg::OnTimer(wxTimerEvent& evt){
  if (theApp.serverconnect->IsConnected()){
    CServer* toask = theApp.serverlist->GetNextSearchServer();
    if (toask == theApp.serverlist->GetServerByAddress(theApp.serverconnect->GetCurrentServer()->GetAddress(),theApp.serverconnect->GetCurrentServer()->GetPort()))
      toask = theApp.serverlist->GetNextSearchServer();
    
    if (toask && theApp.serverlist->GetServerCount()-1 != servercount){
      servercount++;
      theApp.serverconnect->SendUDPPacket(searchpacket,toask,false);
      //searchprogress.StepIt();
      searchprogress->SetValue(searchprogress->GetValue()+1);
    }
    else
      OnBnClickedCancels(nullEvent);
      //printf("Cancel-test\n");
      //m_timer.Stop();
  }
  else 
    OnBnClickedCancels(nullEvent);
    //printf("Cancel-test\n");
    //m_timer.Stop();
}

void CSearchDlg::CreateNewTab(wxString searchString,uint32 nSearchID)
{
  // open new search window
  CMuleNotebook* nb=XRCCTRL(*this,"ID_NOTEBOOK",CMuleNotebook);
  wxPanel* sizCont=new wxPanel(nb,-1);
  wxSizer *content=searchPage(sizCont,TRUE);
  nb->AddPage(sizCont,searchString,TRUE,0,nSearchID);

  wxGauge* gauge=(wxGauge*)sizCont->FindWindowById(ID_SEARCHPROGRESS,sizCont);
  searchprogress=gauge;
  //printf("Searchprogress=%lx\n");
  // set the range here!
  searchprogress->SetRange(theApp.serverlist->GetServerCount()-1);

  GetParent()->Layout();
  searchlistctrl=(CSearchListCtrl*)sizCont->FindWindowById(ID_SEARCHLISTCTRL,sizCont);
  searchlistctrl->Init(theApp.searchlist);
  theApp.searchlist->SetOutputWnd(searchlistctrl);

  searchlistctrl->ShowResults(nSearchID);
}

void CSearchDlg::OnBnClickedCancels(wxEvent &evt){
  canceld = true;
  globsearch = false;
  if (global_search_timer){    
    delete searchpacket;
    //KillTimer(global_search_timer);
    m_timer.Stop();
    global_search_timer = 0;
    if(searchprogress) searchprogress->SetValue(0);
  }
  XRCCTRL(*this,"IDC_STARTS",wxButton)->Enable(true);
  XRCCTRL(*this,"IDC_CANCELS",wxButton)->Enable(false); 
 //this->GetDlgItem(IDC_CANCELS)->EnableWindow(false);
  //this->GetDlgItem(IDC_STARTS)->EnableWindow(true);
}

void CSearchDlg::LocalSearchEnd(uint16 count){
  if (!canceld && count > MAX_RESULTS) {
    OnBnClickedCancels(nullEvent);
  }
  if (!canceld){	
    if (!globsearch){
      XRCCTRL(*this,"IDC_STARTS",wxButton)->Enable(true);
      XRCCTRL(*this,"IDC_CANCELS",wxButton)->Enable(false);
      //this->GetDlgItem(IDC_STARTS)->EnableWindow(true);
      //this->GetDlgItem(IDC_CANCELS)->EnableWindow(false);
    }
    else {
      //global_search_timer = SetTimer(1, 750, 0);
      m_timer.Start(750);
      global_search_timer=(UINT*)1;
    }
  }
}
void CSearchDlg::AddUDPResult(uint16 count){
	if (!canceld && count > MAX_RESULTS)
	  OnBnClickedCancels(nullEvent);
}

void CSearchDlg::OnBnClickedSdownload(wxCommandEvent &evt){
	//start download(s)
	DownloadSelected();
}

#if 0
BOOL CSearchDlg::PreTranslateMessage(MSG* pMsg) 
{
   if((pMsg->message == WM_KEYDOWN) && (pMsg->wParam == 13)){
	   if (pMsg->hwnd == GetDlgItem(IDC_SEARCHLIST)->m_hWnd)
			OnBnClickedSdownload();
	   else if (pMsg->hwnd == GetDlgItem(IDC_ELINK)->m_hWnd)
			OnBnClickedStarts();
	   else if (pMsg->hwnd == GetDlgItem(IDC_SEARCHNAME)->m_hWnd)
			OnBnClickedStarts();
   }

   return CResizableDialog::PreTranslateMessage(pMsg);
}
#endif

#if 0
void CSearchDlg::OnNMDblclkSearchlist(NMHDR *pNMHDR, LRESULT *pResult){
	OnBnClickedSdownload();
	*pResult = 0;
}
#endif

wxString CSearchDlg::CreateWebQuery(){
	wxString query;
	query = "http://www.filedonkey.com/fdsearch/index.php?media=";
	//switch (typebox.GetCurSel()){
	int x=1;
	switch(x){
		case 1:
			query += "Audio";
			break;
		case 2:
			query += "Video";
			break;
		case 3:
			query += "Pro";
			break;
		default:
			;
	}
	CString tosearch;
	//GetDlgItem(IDC_SWEB)->GetWindowText(tosearch);
	tosearch = CString(URLEncode(tosearch).GetData());
	tosearch.Replace("%20","+");
	query += "&pattern=";
	query += tosearch;
	query += "&action=search&name=FD-Search&op=modload&file=index&requestby=emule";
	return query;
}

void CSearchDlg::DownloadSelected() {
#if 0 
 int index = -1; 
  POSITION pos = searchlistctrl.GetFirstSelectedItemPosition(); 
  while(pos != NULL) 
    { 
      index = searchlistctrl.GetNextSelectedItem(pos); 
      if(index > -1) {
	theApp.downloadqueue->AddSearchToDownload((CSearchFile*)searchlistctrl.GetItemData(index ));
	searchlistctrl.Update(index);
      }
    } 
#endif
  int index=-1;
  // download from the selected page.
  CSearchListCtrl* oldlist=searchlistctrl;
  CMuleNotebook* nb=XRCCTRL(*this,"ID_NOTEBOOK",CMuleNotebook);
  if(nb->GetSelection()==-1) {
    return;
  }

  searchlistctrl=(CSearchListCtrl*)nb->FindWindowById(ID_SEARCHLISTCTRL,nb->GetPage(nb->GetSelection()));

  for(;;) {
    index=searchlistctrl->GetNextItem(index,wxLIST_NEXT_ALL,wxLIST_STATE_SELECTED);
    if(index==-1)
      break;
    theApp.downloadqueue->AddSearchToDownload((CSearchFile*)searchlistctrl->GetItemData(index));
  }
  searchlistctrl=oldlist;

}


void CSearchDlg::Localize(){
  //searchlistctrl.Localize();

  GetDlgItem(IDC_SEARCH_FRM,wxControl)->SetLabel(GetResString(IDS_SW_SEARCHBOX));
  GetDlgItem(IDC_MSTATIC3,wxControl)->SetLabel(GetResString(IDS_SW_NAME));
  GetDlgItem(IDC_SGLOBAL,wxControl)->SetLabel(GetResString(IDS_SW_GLOBAL));
  GetDlgItem(IDC_MSTATIC7,wxControl)->SetLabel(GetResString(IDS_SW_TYPE));
  GetDlgItem(IDC_WEBSEARCH_FRM,wxControl)->SetLabel(GetResString(IDS_SW_WEBBASED));
  GetDlgItem(IDC_MSTATIC4,wxControl)->SetLabel(GetResString(IDS_SW_TYPE));
  GetDlgItem(IDC_NAME21,wxControl)->SetLabel(GetResString(IDS_SW_NAME));
  GetDlgItem(IDC_DDOWN_FRM,wxControl)->SetLabel(GetResString(IDS_SW_DIRECTDOWNLOAD));
  GetDlgItem(IIDC_FSTATIC2,wxControl)->SetLabel(GetResString(IDS_SW_LINK));
  GetDlgItem(IDC_STARTS,wxControl)->SetLabel(GetResString(IDS_SW_START));
  GetDlgItem(IDC_CANCELS,wxControl)->SetLabel(GetResString(IDS_CANCEL));
  GetDlgItem(IDC_CLEARALL,wxControl)->SetLabel(GetResString(IDS_REMOVEALLSEARCH));
  GetDlgItem(IDC_RESULTS_LBL,wxControl)->SetLabel(GetResString(IDS_SW_RESULT));
  GetDlgItem(IDC_SDOWNLOAD,wxControl)->SetLabel(GetResString(IDS_SW_DOWNLOAD));
  GetDlgItem(IDC_MSTATIC4,wxControl)->SetLabel(GetResString(IDS_TYPE));
  GetDlgItem(IDC_MSTATIC7,wxControl)->SetLabel(GetResString(IDS_TYPE));
  GetDlgItem(IDC_SEARCH_RESET,wxControl)->SetLabel(GetResString(IDS_PW_RESET));	
  
  GetDlgItem(IDC_SEARCHMINSIZE,wxControl)->SetLabel(GetResString(IDS_SEARCHMINSIZE)+":");
  GetDlgItem(IDC_SEARCHMAXSIZE,wxControl)->SetLabel(GetResString(IDS_SEARCHMAXSIZE)+":");
  GetDlgItem(IDC_SEARCHEXTENTION,wxControl)->SetLabel(GetResString(IDS_SEARCHEXTENTION)+":");
  GetDlgItem(IDC_SEARCHAVAIL,wxControl)->SetLabel(GetResString(IDS_SEARCHAVAIL)+":");
  
  wxChoice* typebox=XRCCTRL(*this,"IDC_COMBO1",wxChoice);
  wxChoice* Stypebox=XRCCTRL(*this,"IDC_TypeSearch",wxChoice);

  while (typebox->GetCount()>0) typebox->Delete(0);
  typebox->Append(GetResString(IDS_SEARCH_ANY));
  typebox->Append(GetResString(IDS_SEARCH_AUDIO));
  typebox->Append(GetResString(IDS_SEARCH_VIDEO));
  typebox->Append(GetResString(IDS_SEARCH_PRG));
  typebox->SetSelection(typebox->FindString(GetResString(IDS_SEARCH_ANY)));
  
  while (Stypebox->GetCount()>0) Stypebox->Delete(0);
  Stypebox->Append(GetResString(IDS_SEARCH_ANY));
  Stypebox->Append(GetResString(IDS_SEARCH_ARC));
  Stypebox->Append(GetResString(IDS_SEARCH_AUDIO));
  Stypebox->Append(GetResString(IDS_SEARCH_CDIMG));
  Stypebox->Append(GetResString(IDS_SEARCH_PICS));
  Stypebox->Append(GetResString(IDS_SEARCH_PRG));
  Stypebox->Append(GetResString(IDS_SEARCH_VIDEO));
  Stypebox->SetSelection(Stypebox->FindString(GetResString(IDS_SEARCH_ANY)));
}

// #if 0
void CSearchDlg::OnBnClickedClearall()
{
	DeleteAllSearchs();
}
// #endif

void CSearchDlg::StartNewSearch(){
  if (!theApp.serverconnect->IsConnected()) {
    //MessageBox(GetResString(IDS_ERR_NOTCONNECTED),GetResString(IDS_NOTCONNECTED),64);
    wxMessageDialog* dlg=new wxMessageDialog(this,GetResString(IDS_ERR_NOTCONNECTED),GetResString(IDS_NOTCONNECTED),wxOK|wxCENTRE|wxICON_INFORMATION);
    dlg->ShowModal();
  } else{
    m_nSearchID++;
    wxString typeText;
    wxString searchString;
    typeText=GetDlgItem(IDC_TypeSearch,wxChoice)->GetStringSelection();
    searchString=GetDlgItem(IDC_SEARCHNAME,wxTextCtrl)->GetValue();
    theApp.searchlist->NewSearch(searchlistctrl,CString(typeText),m_nSearchID);
    GetDlgItem(IDC_STARTS,wxControl)->Enable(false);
    GetDlgItem(IDC_CANCELS,wxControl)->Enable(true);
    canceld = false;
    
    long typeNemonic=      0x00030001;
    long extensionNemonic= 0x00040001;
    long avaibilityNemonic=0x15000101;
    long minNemonic=       0x02000101;
    long maxNemonic=	   0x02000102;
    byte stringParameter=1;
    byte typeParameter=2;
    byte numericParameter=3;
    int andParameter=0x0000;
    int orParameter=0x0100;
    
    CMemFile* data = new CMemFile(100); 
    uint16 nSize;
    char* formatC;
    unsigned long avaibility;
    
    wxString sizeMin,sizeMax,extension,avaibilitystr,type;
    sizeMin=GetDlgItem(IDC_EDITSEARCHMIN,wxTextCtrl)->GetValue();
    sizeMax=GetDlgItem(IDC_EDITSEARCHMAX,wxTextCtrl)->GetValue();
    unsigned long max=atol(sizeMax.GetData())*1048576; 
    unsigned long min=atol(sizeMin.GetData())*1048576; 
    if (max==0 || max<min) max=2147483646;//max file size 
    
    extension=GetDlgItem(IDC_EDITSEARCHEXTENSION,wxTextCtrl)->GetValue();
    if (extension.Length()>0 && extension.GetChar(0)!='.' ) extension="."+extension;
    type="";
    if (GetResString(IDS_SEARCH_AUDIO)==typeText) type.Printf("Audio"); 
    if (GetResString(IDS_SEARCH_VIDEO)==typeText) type.Printf("Video"); 
    if (GetResString(IDS_SEARCH_PRG)==typeText) type.Printf("Pro"); 
    if (GetResString(IDS_SEARCH_PICS)==typeText) type.Printf("Image"); 
    
    avaibilitystr=GetDlgItem(IDC_EDITSEARCHAVAIBILITY,wxTextCtrl)->GetValue();
    avaibility=atol(avaibilitystr.GetData());
    
    if ( searchString.Length()==0 && extension.Length()==0) 
      {
	delete data;
	return;
      }
    
    int parametercount=0; //must be written parametercount-1 parmeter headers
    
    if ( searchString.Length()>0)
      {
	parametercount++;
	if (parametercount>1)
	  data->Write(&andParameter,2);
      }
    
    if (type.Length()>0)
      {
	parametercount++;
	if (parametercount>1)
	  data->Write(&andParameter,2);
      }
    
    if (min>0)
      {
	parametercount++;
	if (parametercount>1)
	  data->Write(&andParameter,2);
      }
    
    if (max>0)
      {
	parametercount++;
	if (parametercount>1)
	  data->Write(&andParameter,2);
      }
    
    if (avaibility>0)
      {
	parametercount++;
	if (parametercount>1)
	  data->Write(&andParameter,2);
      }
    
    if (extension.Length()>0)
      {
	parametercount++;
	if (parametercount>1)
	  data->Write(&andParameter,2);
      }
    
    //body
    if (searchString.Length()>0) //search a string
      {
	data->Write(&stringParameter,1); //write the parameter type
	nSize = GetDlgItem(IDC_SEARCHNAME,wxTextCtrl)->GetValue().Length();
	data->Write(&nSize,2);  // write parameter length
	char* searchstr = new char[nSize+1]; 
	strcpy(searchstr,GetDlgItem(IDC_SEARCHNAME,wxTextCtrl)->GetValue().GetData());
	data->Write(searchstr,nSize); //write the searched string 
	delete[] searchstr; 
      }
    
    if (type.Length()>0)
      {
	data->Write(&typeParameter,1); //write the parameter type
	nSize=type.Length(); 
	data->Write(&nSize,2);   //write the length
	formatC=(char*)type.GetData();
	data->Write(formatC,nSize); //write parameter
	data->Write(&typeNemonic,3); //nemonic for this kind of parameter (only 3 bytes!!)
      }
    
    if (min>0)
      {
	data->Write(&numericParameter,1); //write the parameter type
	data->Write(&min,4);		   //write the parameter
	data->Write(&minNemonic,4);    //nemonic for this kind of parameter
      }
    
    if (max>0)
      {
	data->Write(&numericParameter,1); //write the parameter type
	data->Write(&max,4);		   //write the parameter
	data->Write(&maxNemonic,4);    //nemonic for this kind of parameter
      }
    
    if (avaibility>0)
      {
	data->Write(&numericParameter,1); //write the parameter type
	data->Write(&avaibility,4);    //write the parameter
	data->Write(&avaibilityNemonic,4);  //nemonic for this kind of parameter
		}
    
    if (extension.Length()>0)
      {
	data->Write(&stringParameter,1); //write the parameter type
	nSize=extension.Length(); 
	data->Write(&nSize,2);   //write the length
	formatC=(char*)extension.GetData();
	data->Write(formatC,nSize); //write parameter
	data->Write(&extensionNemonic,3); //nemonic for this kind of parameter (only 3 bytes!!)
      }
    
    
    Packet* packet = new Packet(data);
    packet->opcode = OP_SEARCHREQUEST;
    delete data;
    theApp.uploadqueue->AddUpDataOverheadServer(packet->size);
    theApp.serverconnect->SendPacket(packet,false);
    
    if (IsDlgButtonChecked(IDC_SGLOBAL)){
      if( theApp.glob_prefs->Score() ){
				theApp.serverlist->ResetSearchServerPos();
      }
      searchpacket = packet;
      searchpacket->opcode = OP_GLOBSEARCHREQ;
      servercount = 0;
      // in createnewtab():
      //searchprogress.SetRange32(0,theApp.serverlist->GetServerCount()-1);
      globsearch = true;
    }
    else{
      globsearch = false;
      delete packet;
    }
    CreateNewTab(searchString,m_nSearchID);
  }
}

void CSearchDlg::DeleteSearch(uint16 nSearchID){
	theApp.searchlist->RemoveResults(nSearchID);
	/*
	  get the searchlist notebook widget
	*/
	CMuleNotebook * nb = XRCCTRL(*this,"ID_NOTEBOOK",CMuleNotebook);
	if(nb == NULL) {
	  // well.. if this actually happens..
	  return;
	}
	
	/*
	  find the searchlist & its parent in the notebooks page list
	*/
#ifdef DEBUG
	printf("debug: want to delete search with id = %d\n", nSearchID);
#endif
	if(nb->GetPageCount() > 0) {
	    /*
	      Remove the notebook page
	    */
    	    for(int i=0; i < nb->GetPageCount(); i++) {
	        /*
		  get searchlist->GetId() from the current notebook entry (?)
		*/
		wxWindow * page = (wxWindow *)nb->GetPage(i);
		wxWindow * slctrl = page->FindWindowById(ID_SEARCHLISTCTRL, page);
		if(!slctrl)
		  continue;

		uint16 sID = ((CSearchListCtrl *)slctrl)->GetSearchId();
#ifdef DEBUG
		printf("debug: searchId=%d | page->slctrl->Id=%d, page->slctrl->searchId=%d | nb->GetPage(%d)->Id=%d\n", nSearchID, slctrl->GetId(), sID, i, page->GetId());
#endif
		/*
		  is this the searchlist tab we want to remove ?
		*/
		if(sID == nSearchID) {
#ifdef DEBUG
		  printf("debug: removing searchId=%d tab\n", sID);
#endif
		  nb->RemovePage(i);
		  /*
		    ToDo: remove searchlistctrl (slctrl) ?
		  */
		  break;
		}
	    }
	}
#if 0
	TCITEM item;
	item.mask = TCIF_PARAM;
	int i;
	for (i = 0; i != searchselect.GetItemCount();i++){
		searchselect.GetItem(i,&item);
		if (item.lParam == nSearchID)
			break;
	}
	if (item.lParam != nSearchID)
		return;
	theApp.searchlist->RemoveResults(nSearchID);
	searchselect.DeleteItem(i);
	if (searchselect.GetItemCount()){
		searchselect.SetCurSel(0);
		item.mask = TCIF_PARAM;
		searchselect.GetItem(0,&item);
		searchlistctrl.ShowResults(item.lParam);
	}
	else{
		searchlistctrl.DeleteAllItems();
		searchselect.ShowWindow(SW_HIDE);
	}
#endif
}

void CSearchDlg::DeleteAllSearchs(){
	theApp.searchlist->Clear();
	/*
	  get the searchlist notebook widget
	*/
	CMuleNotebook * nb = XRCCTRL(*this,"ID_NOTEBOOK",CMuleNotebook);
	if(nb == NULL) {
	  printf("error: nb=NULL in deletesearch\n");
	  return;
	}

	if(nb->GetPageCount() > 0) {
	    /*
	      Remove all notebook pages
	    */
    	    for(int i=nb->GetPageCount()-1; i>=0; i--) {
		if(nb->GetPage(i) != NULL)
    		    nb->RemovePage(i);
		  /*
		    ToDo: remove searchlistctrl (slctrl) ?
		  */
	    }
	}
#if 0
	searchlistctrl.DeleteAllItems();
	searchselect.ShowWindow(SW_HIDE);
	searchselect.DeleteAllItems();
#endif
	printf("todo. deleteallsearchs\n");
}


void CSearchDlg::OnBnClickedSearchReset(wxEvent& evt)
{
	GetDlgItem(IDC_EDITSEARCHAVAIBILITY,wxTextCtrl)->SetValue("");	
	GetDlgItem(IDC_EDITSEARCHEXTENSION,wxTextCtrl)->SetValue("");	
	GetDlgItem(IDC_EDITSEARCHMIN,wxTextCtrl)->SetValue("");	
	GetDlgItem(IDC_EDITSEARCHMAX,wxTextCtrl)->SetValue("");	
	GetDlgItem(IDC_SEARCHNAME,wxTextCtrl)->SetValue("");
	wxChoice* Stypebox=XRCCTRL(*this,"IDC_TypeSearch",wxChoice);
	Stypebox->SetSelection(Stypebox->FindString(GetResString(IDS_SEARCH_ANY)));

	//OnEnChangeSearchname();
}

#if 0
void CSearchDlg::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
{
	TCITEM item;
	item.mask = TCIF_PARAM;
	int cur_sel = searchselect.GetCurSel();
	if (cur_sel == (-1))
		return;
	searchselect.GetItem(cur_sel,&item);
	searchlistctrl.ShowResults(item.lParam);
	*pResult = 0;
}
#endif
